package owl2vowl.parser.owlapi;

import javax.annotation.Nonnull;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAnonymousIndividual;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLIndividual;
import org.semanticweb.owlapi.model.OWLIndividualVisitor;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLOntologyManager;

import owl2vowl.model.data.VowlData;
import owl2vowl.model.individuals.VowlIndividual;
import owl2vowl.parser.vowl.AnnotationParser;

public class IndividualsVisitor implements OWLIndividualVisitor {
	private final VowlData vowlData;
	protected IRI baseIRI;
	private OWLOntologyManager manager;
	private Logger logger = LogManager.getLogger(IndividualsVisitor.class);

	public IndividualsVisitor(VowlData vowlData, OWLIndividual owlIndividual, OWLClass baseClass,
			OWLOntologyManager manager) {
		this.vowlData = vowlData;
		this.manager = manager;
		this.baseIRI = baseClass.getIRI();
	}

	public IndividualsVisitor(VowlData vowlData, OWLOntologyManager manager, IRI baseIRI) {
		this.vowlData = vowlData;
		this.manager = manager;
		this.baseIRI = baseIRI;
	}

	public void visit(@Nonnull OWLNamedIndividual owlNamedIndividual) {
		if (this.vowlData.getClassMap().containsKey(owlNamedIndividual.getIRI())) {
			this.vowlData.getClassForIri(this.baseIRI).addInstance(owlNamedIndividual.getIRI());
			this.vowlData.getGenerator().generateTypeOf(this.baseIRI, owlNamedIndividual.getIRI());
		} else {
			this.vowlData.getClassForIri(this.baseIRI).addIndividual(this.createIndividual(owlNamedIndividual));
		}

	}

	private IRI createIndividual(OWLNamedIndividual owlNamedIndividual) {
		VowlIndividual individual = this.vowlData.getGenerator().generateIndividual(owlNamedIndividual.getIRI());
		(new AnnotationParser(this.vowlData, this.manager)).parse(individual);
		return individual.getIri();
	}

	public void visit(@Nonnull OWLAnonymousIndividual owlAnonymousIndividual) {
		this.logger.info("Anonymous individual: " + owlAnonymousIndividual);
	}
}